/*-------------------------------------------------------------------------
 *
 * pg_publication.h
 *	  "发布" 系统目录 (pg_publication) 的定义
 *
 * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * src/include/catalog/pg_publication.h
 *
 * NOTES
 *	  Catalog.pm 模块读取此文件并推导模式信息。
 *
 *-------------------------------------------------------------------------
 */
#ifndef PG_PUBLICATION_H
#define PG_PUBLICATION_H

#include "catalog/genbki.h"
#include "catalog/objectaddress.h"
#include "catalog/pg_publication_d.h"

/* ----------------
 *		pg_publication 定义。cpp 将其转化为
 *		typedef struct FormData_pg_publication
 * ----------------
 */
CATALOG(pg_publication,6104,PublicationRelationId)
{
	Oid			oid;			/* oid */

	NameData	pubname;		/* 发表名称 */

	Oid			pubowner BKI_LOOKUP(pg_authid); /* 发布者 */

	/*
	 * 表示这是一个特殊的发布，应涵盖数据库中的所有
	 * 表（除了未记录和临时表）
	 */
	bool		puballtables;

	/* 如果插入被发布则为真 */
	bool		pubinsert;

	/* 如果更新被发布则为真 */
	bool		pubupdate;

	/* 如果删除被发布则为真 */
	bool		pubdelete;

	/* 如果截断被发布则为真 */
	bool		pubtruncate;

	/* 如果使用根模式发布分区更改则为真 */
	bool		pubviaroot;
} FormData_pg_publication;

/* ----------------
 *		Form_pg_publication对应指向具有
 *		pg_publication关系格式的元组的指针。
 * ----------------
 */
typedef FormData_pg_publication *Form_pg_publication;

DECLARE_UNIQUE_INDEX_PKEY(pg_publication_oid_index, 6110, PublicationObjectIndexId, on pg_publication using btree(oid oid_ops));
DECLARE_UNIQUE_INDEX(pg_publication_pubname_index, 6111, PublicationNameIndexId, on pg_publication using btree(pubname name_ops));

typedef struct PublicationActions
{
	bool		pubinsert;
	bool		pubupdate;
	bool		pubdelete;
	bool		pubtruncate;
} PublicationActions;

typedef struct PublicationDesc
{
	PublicationActions pubactions;

	/*
	 * 如果在行过滤器中引用的列用于 UPDATE
	 * 或 DELETE 是复制身份的一部分，或者发布操作
	 * 不包括 UPDATE 或 DELETE，则为 true。
	 */
	bool		rf_valid_for_update;
	bool		rf_valid_for_delete;

	/*
	 * 如果这些列是复制身份的一部分，或者发布
	 * 操作不包括 UPDATE 或 DELETE，则为 true。
	 */
	bool		cols_valid_for_update;
	bool		cols_valid_for_delete;
} PublicationDesc;

typedef struct Publication
{
	Oid			oid;
	char	   *name;
	bool		alltables;
	bool		pubviaroot;
	PublicationActions pubactions;
} Publication;

typedef struct PublicationRelInfo
{
	Relation	relation;
	Node	   *whereClause;
	List	   *columns;
} PublicationRelInfo;

extern Publication *GetPublication(Oid pubid);
extern Publication *GetPublicationByName(const char *pubname, bool missing_ok);
extern List *GetRelationPublications(Oid relid);

/*---------
 * GetRelationPublications() 中 pub_partopt 参数的预期值，
 * 允许调用者指定他们期望在发布中看到的分区表的哪些分区。
 *
 *	ROOT:	仅发布中明确提到的表
 *	LEAF:	仅给定树中的叶子分区
 *	ALL:	给定树中的所有分区
 */
typedef enum PublicationPartOpt
{
	PUBLICATION_PART_ROOT,
	PUBLICATION_PART_LEAF,
	PUBLICATION_PART_ALL,
} PublicationPartOpt;

extern List *GetPublicationRelations(Oid pubid, PublicationPartOpt pub_partopt);
extern List *GetAllTablesPublications(void);
#ifdef FDDM
extern List *GetAllTablesPublicationRelations(bool pubviaroot, bool skipFddmSchema, bool includePartition);
#else
extern List *GetAllTablesPublicationRelations(bool pubviaroot);
#endif //FDDM
extern List *GetPublicationSchemas(Oid pubid);
extern List *GetSchemaPublications(Oid schemaid);
extern List *GetSchemaPublicationRelations(Oid schemaid,
										   PublicationPartOpt pub_partopt);
extern List *GetAllSchemaPublicationRelations(Oid puboid,
											  PublicationPartOpt pub_partopt);
extern List *GetPubPartitionOptionRelations(List *result,
											PublicationPartOpt pub_partopt,
											Oid relid);
extern Oid	GetTopMostAncestorInPublication(Oid puboid, List *ancestors,
											int *ancestor_level);

extern bool is_publishable_relation(Relation rel);
extern bool is_schema_publication(Oid pubid);
extern ObjectAddress publication_add_relation(Oid pubid, PublicationRelInfo *pri,
											  bool if_not_exists);
extern ObjectAddress publication_add_schema(Oid pubid, Oid schemaid,
											bool if_not_exists);

extern Bitmapset *pub_collist_to_bitmapset(Bitmapset *columns, Datum pubcols,
										   MemoryContext mcxt);

extern Oid	get_publication_oid(const char *pubname, bool missing_ok);
extern char *get_publication_name(Oid pubid, bool missing_ok);

#endif							/* PG_PUBLICATION_H */
